﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Conusic;
using Conusic.Properties;

namespace MusicPage
{
    public partial class MusicPage : UserControl, IAudioSearchCommand
    {
        private const int BitrateViewIndex = 4;
        private const int DownloadedKbIndex = 3;

        public MusicPage()
        {
            InitializeComponent();

            textBoxDownloadDirectory.Text = Settings.Default.DownloadDirectory;
        }

        private void Button1Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            VkontakteAudio.SearchAudioAsync(this, textBoxSearchText.Text);
        }

        void IAudioSearchCommand.Execute(List<AudioRecord> listAudio)
        {
            SafeUpdateListView(listAudio);
        }

        private void ListView1ColumnClick(object sender, ColumnClickEventArgs e)
        {
            var comparer = listView1.ListViewItemSorter as MusicPageViewSorter;
            if (comparer == null)
            {
                comparer = new MusicPageViewSorter();
                listView1.ListViewItemSorter = comparer;
            }
            comparer.SetColumnSorting(e.Column);
            listView1.Sort();
        }

        private void TextBoxSearchTextKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                Button1Click(sender, null);
            }
        }

        private void ContextMenuTrackOpening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            int count = listView1.SelectedItems.Count;
            string returnRightForm = RussianNumbers.ReturnRightForm(count, "композицию", "композиции", "композиций");
            string returnRightForm2 = RussianNumbers.ReturnRightForm(count, "композиции", "композиций", "композиций");

            загрузитьToolStripMenuItem.Text = String.Format("Загрузить {0} {1}", count, returnRightForm);
            получитьРазмерИБитрейтToolStripMenuItem.Text = String.Format("Получить битрейт для {0} {1}", count,
                                                                         returnRightForm2);
        }

        private void StartLoadSong(AudioRecord record, ListViewItem item)
        {
            if (record == null) throw new ArgumentNullException("record");

            if (!String.IsNullOrEmpty(record.Url))
            {
                //var downSong = new DownSong(record);
                string saveToFile = record.FullFilename;

                var downloadFile = new DownloadFile(record.Url, saveToFile);
                downloadFile.OnFileComplete += (fileEventArgs) =>
                                               {
                                                   UpdateItemListViewText(item, "загружено", DownloadedKbIndex);
                                                   item.BackColor = Color.LightGreen;
                                               };

                downloadFile.OnFileFail += (fileEventArgs) =>
                                               {
                                                   ConusicUI.ErrorReport.Show(fileEventArgs.Exc, null);
                                                   UpdateItemListViewText(item, "Ошибка! ", DownloadedKbIndex);
                                               };
                DateTime lastUpdateTime = DateTime.MinValue;

                // timeSpan is not Value type - we can use it in new delegate
                var timeSpan = new TimeSpan(0, 0, 0, 0, 500);
                downloadFile.OnProgressFile += (args) =>
                                           {
                                               if (DateTime.Now - lastUpdateTime < timeSpan)
                                                   return;

                                               lastUpdateTime = DateTime.Now;
                                               string a = String.Format("{2}% {0} Kb/{1}Kb",
                                                   args.DownloadedKb,
                                                   args.TotalKb,
                                                   (int)args.Downloaded * 100 / args.Total);

                                               UpdateItemListViewText(item, a, DownloadedKbIndex);
                                               string s = String.Format("{0:D3} bps",
                                                                        Convert.ToInt32(args.Total * 8 / 1024.0 / record.Duration));
                                               UpdateItemListViewText(item, s, BitrateViewIndex);
                                           };

                downloadFile.DownloadAsync();
            }
            else
            {
                // not implemented feature
                var ts = new ThreadStart(delegate()
                                             {
                                                 //AudioRecord = VkontakteAudio.
                                             });
                var thread = new Thread(ts);
                thread.Start();
            }
        }

        private delegate void UpdateListDelegate(ListViewItem item);

        private void UpdateItemListViewText(ListViewItem item, string text, int subitemIndex)
        {
            if (listView1.InvokeRequired)
            {
                listView1.Invoke(new MethodInvoker(() => UpdateItemListViewText(item, text, subitemIndex)));
            }
            else
            {
                item.SubItems[subitemIndex].Text = text;
            }
        }

        private void VkontakteButton1Click(object sender, EventArgs e)
        {
            StartLoadSeletedItems();
        }

        private void DownloadToolStripMenuItemClick(object sender, EventArgs e)
        {
            StartLoadSeletedItems();
        }

        private void GetSizeAndBitrateToolStripMenuItemClick(object sender, EventArgs e)
        {
            foreach (ListViewItem item in listView1.SelectedItems)
            {
                ListViewItem item1 = item;
                var s = new ThreadStart(() =>
                                            {
                                                if (item1 != null && item1.Tag as AudioRecord != null)
                                                {
                                                    var averageBitrate =
                                                        VkontakteAudio.GetAverageBitrate(item1.Tag as AudioRecord);
                                                    string text = String.Format("{0:D3} kbps", averageBitrate);
                                                    UpdateItemListViewText(item1, text, BitrateViewIndex);
                                                }
                                            });
                var thread = new Thread(s);
                thread.Start();
            }
        }

        private void StartLoadSeletedItems()
        {
            foreach (ListViewItem item in listView1.SelectedItems)
            {
                StartLoadSong(item.Tag as AudioRecord, item);
            }
        }

        private void Button2Click(object sender, EventArgs e)
        {
            var browserDialog = new FolderBrowserDialog
                                    {
                                        Description = @"Пожалуйста, выберите папку для сохранения файлов",
                                        SelectedPath = textBoxDownloadDirectory.Text
                                    };
            if (browserDialog.ShowDialog() == DialogResult.OK)
            {
                textBoxDownloadDirectory.Text = browserDialog.SelectedPath;
            }
        }

        private void top100ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var ts = new ThreadStart(delegate()
                                         {
                                             try
                                             {
                                                 var list = PiterMoskvaFm.GetTop100PiterFm();
                                                 SafeUpdateListView(list);
                                             }
                                             catch (Exception ext)
                                             {
                                                 ConusicUI.ErrorReport.Show(ext);
                                             }
                                         });
            var th = new Thread(ts);
            th.Start();
        }

        private void SafeUpdateListView(IEnumerable<AudioRecord> list)
        {
            if (listView1.InvokeRequired)
            {
                listView1.Invoke(new MethodInvoker(() => SafeUpdateListView(list)));
            }
            else
            {
                listView1.Items.Clear();
                foreach (AudioRecord item in list)
                {
                    var newItem = new ListViewItem { Text = item.Artist };
                    newItem.SubItems.Add(item.CompositionName);
                    newItem.SubItems.Add(item.DurationMs);
                    newItem.SubItems.Add(String.Empty); // size
                    newItem.SubItems.Add(String.Empty); // bitrate

                    newItem.Tag = item;
                    listView1.Items.Add(newItem);
                }
            }
        }

        private void TextBoxDownloadDirectoryTextChanged(object sender, EventArgs e)
        {
            Settings.Default.DownloadDirectory =  textBoxDownloadDirectory.Text;
        }
    }

}